
package com.y.fund.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Random;
import java.util.UUID;

public class StrUtil {
	
	public static final String SPLIT_CHAR = ";";

	public static final String CHARSET_UTF8 = "UTF-8";

	private final static String hexDigits = "0123456789ABCDEF";

	private final static String ZeroStr = "0000000000000000000000000000";

    // 要使用生成 URL 的字符
    private static final String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h",
            "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
            "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H",
            "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z"
    };
    
    
    /** 一个空字符串. */
    /** The empty String {@code ""}.*/
    public static final String EMPTY = "";
    
	private static final Random random = new Random();

	/**给不够长的字符串左侧补0，只补长， 不截取； 比如规范数字的字符串形式长度，如：2 变成 002 */
    public static String FillZeroLeft(String ostr, int fullLength) {
    	if(null==ostr) {
    		ostr = "";
    	}
    	if(fullLength<= ostr.length()) {
    		return ostr;
    	}
    	
    	return ZeroStr.substring(0, fullLength-ostr.length()) + ostr;
    }
    
    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((!Character.isWhitespace(str.charAt(i)))) {
                return false;
            }
        }
        return true;
    }

    public static boolean isBlankIncNullStr(String str) {
		return str == null || str.trim().length() < 1
				|| str.trim().equalsIgnoreCase("null") || str.trim().equalsIgnoreCase("undefined");
	}
    
   public static boolean NotBlank(String str) {
       return !isBlank(str);
   }
   
   public static boolean NotBlankIgnoreNullStr(String str) {
       return !isBlankIncNullStr(str);
   }
   
	public static String[] split(String str){
		return split(str, SPLIT_CHAR);
	}

	public static String[] split(String str, String seperator){
		LinkedList<String> slist =SplitList(str, seperator);
		return slist.toArray(new String[slist.size()]);
	}

	public static LinkedList<String> SplitList(String str, String seperator){

		LinkedList<String> slist = new LinkedList<String>();
		if(null==str || null==seperator){
			return slist;
		}
		if(str.indexOf(seperator)<0){
			slist.add(str);
			return slist;
		}
		int sprlen = seperator.length();
		while(str.indexOf(seperator) > -1){
			slist.add(str.substring(0,str.indexOf(seperator)));
			str = str.substring(str.indexOf(seperator) + sprlen);
		}
		if(str.length()>0){
			slist.add(str);
		}
		return slist;
	}


	@SuppressWarnings("rawtypes")
	public static String join(final Collection array, final String separator) {
        if (array == null) {
            return null;
        }
        return join(array.toArray(), separator, 0, array.size());
   }
	   
   public static String join(final Object[] array, final String separator) {
        if (array == null) {
            return null;
        }
        return join(array, separator, 0, array.length);
    }

	 public static String join(final Collection array, String separator, final int startIndex, final int endIndex) {
        if (array == null) {
            return null;
        }
        return join(array.toArray(), separator, startIndex, endIndex);
	 }
	
	 public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) {
	        if (array==null || startIndex<0 || array.length<endIndex) {//下标越界了
	            return null;
	        }
	        if (separator == null) {
	            separator = EMPTY;
	        }
	        // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
	        //           (Assuming that all Strings are roughly equally long)
	        final int noOfItems = endIndex - startIndex;
	        if (noOfItems <= 0) {
	            return EMPTY;
	        }
	        final StringBuffer buf = new StringBuffer(noOfItems * 55);

            buf.append(array[startIndex]);//先抽取第一个，方便后面的for循环写代码
	        for (int i = startIndex+1; i < endIndex; i++) {
           	 	buf.append(separator).append(array[i]);
	        }
	        return buf.toString();
	    }

	 
	public static long longVal(String longStr){
		if(null==longStr || "".equals(longStr.trim()) || "null".equals(longStr.trim()) || "undefined".equals(longStr.trim())){ return 0L;}
		try{
			return Long.parseLong(longStr);
		}catch(Exception e){
			System.out.println("call ZdStr.longVal(String longStr) error; intStr=".concat(longStr));
			e = null;
		}
		return 0L;
	}
	
	public static int intVal(String intStr){
		return intVal(intStr, null);
	}
	
	public static int intVal(String intStr, Integer defaultVal){
		if(null == defaultVal) {
			defaultVal = 0;
		}
		if(null==intStr || "".equals(intStr.trim()) || "null".equals(intStr.trim()) || "undefined".equals(intStr.trim())){ 
			return defaultVal;
		}
		try{
			if(intStr.indexOf(".") > -1){
				return (int) Float.parseFloat(intStr);
			}else if("true".equalsIgnoreCase(intStr)){
				return 1;
			}else if("false".equalsIgnoreCase(intStr)){
				return 0;
			}
			return Integer.parseInt(intStr);
		}catch(Exception e){
			e = null;
			System.out.println("call ZdStr.intValue(String intStr) error; intStr=".concat(intStr));
		}
		return defaultVal;
	}

	public static Integer IntegerValue(String integerStr){
		if(null==integerStr || "".equals(integerStr.trim()) || "null".equals(integerStr.trim()) || "undefined".equals(integerStr.trim())){ 
			return null;
		}
		try{
			return Integer.valueOf(integerStr);
		}catch(Exception e){
			e = null;
			System.err.println("call ZdStr.getIntegerValue(String integerStr) error; intStr=" + integerStr);
		}
		return null;
	}

	/** Generates a random, all numeric string based on the specified length  */
	public static String randomNum(int strLen){
		if(strLen < 1){
			return "";
		}
		int i= 0;
		StringBuffer sb = new StringBuffer(strLen);
		while((i++) < strLen){
			sb.append(random.nextInt(10));
		}
		return sb.toString();
	}
    public static String bytes2HexStr(byte[] b) {
        String stmp="";  
        StringBuilder sb = new StringBuilder();  
        for (int n=0;n<b.length;n++){  
            stmp = Integer.toHexString(b[n] & 0xFF);  
            if(stmp.length() < 2){
                sb.append("0");
            }
            sb.append(stmp);
        }  
        return sb.toString().toUpperCase();  
    }
    
    /** Convert hexadecimal string to binary */
    public static byte[] hex2Bytes(String hexStr) {
        if (isBlank(hexStr)){
        	return null;
        }
          
        char[] hexs = hexStr.toUpperCase().toCharArray();    
        byte[] bytes = new byte[hexStr.length() / 2];    
        int n;    

        for (int i = 0; i < bytes.length; i++)  
        {    
            n = hexDigits.indexOf(hexs[2 * i]) * 16;    
            n += hexDigits.indexOf(hexs[2 * i + 1]);    
            bytes[i] = (byte) (n & 0xff);    
        }    
        return bytes;    
    }
    
	 /**Replace characters in a circular way, so that even if the characters to be replaced are special characters of regular expressions, such as\ Etc. can also be replaced */
	public static String replaceAll(String str, String regStr, String replaceStr) {
		if(str==null){
			return null;
		}
		if(regStr==null || "".equals(regStr.trim()) || replaceStr==null || regStr.equals(replaceStr)){
			return str;
		}
		StringBuffer newStr = new StringBuffer();
		int strIndex = str.indexOf(regStr);
		while(strIndex != -1){
			newStr.append(str.substring(0, strIndex)).append(replaceStr);
			str = str.substring(strIndex + regStr.length());
			if(str.length()<1){
				strIndex = -1;
			}
			strIndex = str.indexOf(regStr);
		}
		if(str.length()>0){
			newStr.append(str);
		}
		return newStr.toString();
	}

	/** UUID生成的32位的字符串  */
	public static String uuId(){
		return UUID.randomUUID().toString().replace("-", "");
	}

    /**获取一个字符串(url)生成的第一个短字符串 */
    public static String shortStr(String originalStr) {
    	if(isBlankIncNullStr(originalStr)) {
    		return null;
    	}
        // 可以自定义生成 MD5 加密字符传前的混合 KEY
        String key = "s_u";
        // 对传入网址进行 MD5 加密
        String hex = md5ByHex(key + originalStr);
     // 把加密字符按照 8 位一组 16 进制与 0x3FFFFFFF 进行位与运算
        String sTempSubString = hex.substring(2 * 8, 2 * 8 + 8);

        // 这里需要使用 long 型来转换，因为 Inteper .parseInt() 只能处理 31 位 , 首位为符号位 , 如果不用long ，则会越界
        long lHexLong = 0x3FFFFFFF & Long.parseLong(sTempSubString, 16);
        String outChars = "";
        for (int j = 0; j < 6; j++) {
            // 把得到的值与 0x0000003D 进行位与运算，取得字符数组 chars 索引
            long index = 0x0000003D & lHexLong;
            // 把取得的字符相加
            outChars += chars[(int) index];
            // 每次循环按位右移 5 位
            lHexLong = lHexLong >> 5;
        }
    
    	return outChars;
    }

    /**
     * MD5加密(32位大写)    
     * @param src
     * @return
     */
    protected static String md5ByHex(String src) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = src.getBytes();
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            String hs = "";
            String stmp = "";
            for (int i = 0; i < hash.length; i++) {
                stmp = Integer.toHexString(hash[i] & 0xFF);
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else {
                    hs = hs + stmp;
                }
            }
            return hs.toUpperCase();
        } catch (Exception e) {
            return "";
        }
    }
    public static String Obj2Str(Object obj){
    	try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    			ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream)){
            objectOutputStream.writeObject(obj);
            String str = byteArrayOutputStream.toString("ISO-8859-1");
        	return str;
    	}catch (Exception e) {
			e.printStackTrace();
		}
        return null;
    }

    public static Object Str2Obj(String str){
    	try(ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.ISO_8859_1));
			ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream)){
    		Object obj = objectInputStream.readObject();
    		return obj;
    	}catch (Exception e) {
			e.printStackTrace();
		}
        return null;
    }
    
    /** 从字符串中过来字符为数字的字符串 */
    public static String GetNumsFromStr(final String cs) {
        if (isBlankIncNullStr(cs)) {
            return "";
        }
        
        final int sz = cs.length();
        StringBuffer nums = new StringBuffer(sz);
        		
        for (int i = 0; i < sz; i++) {
            if (Character.isDigit(cs.charAt(i))) {
            	nums.append(cs.charAt(i));
            }
        }
        return nums.toString();
    }

}
